package com.xnck.ifpms.service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Criteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xnck.ifpms.dao.ActionDao;
import com.xnck.ifpms.dao.ActionResourceDao;
import com.xnck.ifpms.dao.ResourceDao;
import com.xnck.ifpms.dao.ResourceTypeDao;
import com.xnck.ifpms.entity.Action;
import com.xnck.ifpms.entity.ActionResource;
import com.xnck.ifpms.entity.Resource;
import com.xnck.ifpms.entity.ResourceType;
import com.xnck.ifpms.model.TreeNode;
import com.xiaoleilu.hutool.DateUtil;
import com.xiaoleilu.hutool.StrUtil;

/**
 * 资源业务逻辑
 * @author zhangmengliang
 *
 */
@Service
public class ResourceService {

	@Autowired
	private ResourceDao resourceDao;
	
	@Autowired
	private ResourceTypeDao resourceTypeDao;
	
	@Autowired
	private ActionDao actionDao;
	
	@Autowired
	private ActionResourceDao actionResourceDao;
	
	/**
	 * 根据条件获得资源的总数量
	 * @param resourceName 资源名称(NULL时忽略，模糊匹配) 
	 * @param remark 资源备注(NULL时忽略，模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Integer getResourcesCount(String resourceName, String remark){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(resourceName)) {
			cri.where().andLike(Resource.FIELD_DISPLAYNAME, "%" + resourceName + "%");
		}
		if (StrUtil.isNotBlank(remark)) {
			cri.where().andLike(Resource.FIELD_REMARK, "%" + remark + "%");
		}
		return resourceDao.searchCount(cri);
	}
	
	/**
	 * 根据条件分页获得资源信息
	 * @param resourceName 资源名称(NULL时忽略，模糊匹配)
	 * @param remark 资源备注(NULL时忽略，模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<Resource> getResources(String resourceName, String remark, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(resourceName)) {
			cri.where().andLike(Resource.FIELD_DISPLAYNAME, "%" + resourceName + "%");
		}
		if (StrUtil.isNotBlank(remark)) {
			cri.where().andLike(Resource.FIELD_REMARK, "%" + remark + "%");
		}
		cri.getOrderBy().desc(Resource.FIELD_ADDTIME);
		return resourceDao.searchByPage(cri, currentPage, pageSize);
	}
	
	/**
	 * 根据资源主键获得资源信息
	 * @param id 主键
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Resource getResource(String id){
		return resourceDao.get(id);
	}
	
	/**
	 * 保存资源信息，如果不存在就新增，如果存在就修改
	 * @param id 主键(为NULL时新增)
	 * @param resourceCode 资源编码
	 * @param resourceName 资源名称
	 * @param resourceType 资源类型
	 * @param remark 备注
	 * @param enable 是否可用
	 * @param curUserId 当前人员ID
	 * @param viewName 所对应的视图名称
	 * @return
	 * @throws Exception
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public Resource saveResource(String id, String resourceCode, String resourceName, 
			String resourceType, String remark, Boolean enable, String curUserId, String viewName) throws Exception{
		Resource resource = null;
		if (StrUtil.isNotBlank(id)) {
			resource = resourceDao.get(id);
		}
		if (null == resource) {
			this.insertResource(resourceCode, resourceName, resourceType, remark, enable, curUserId, viewName);
		}
		else {
			this.updateResource(resource, resourceCode, resourceName, resourceType, remark, enable, viewName);
		}
		return resource;
	}
	
	/**
	 * 新增资源信息
	 * @param resourceCode 资源编码
	 * @param resourceName 资源名称
	 * @param resourceType 资源类型
	 * @param remark 备注
	 * @param enable 是否可用
	 * @param curUserId 当前人员ID
	 * @param viewName 所属视图名称
	 * @return
	 * @throws Exception
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	private Resource insertResource(String resourceCode, String resourceName, String resourceType, String remark, 
			Boolean enable, String curUserId, String viewName) throws Exception{
		List<Resource> resources = resourceDao.search(Cnd.where(Resource.FIELD_CODE, "=", resourceCode));
		if (resources.size() > 0) {
			throw new Exception("编码已存在");
		}
		Resource resource = new Resource();
		resource.setId(UUID.randomUUID().toString());
		resource.setCode(resourceCode);
		resource.setDisplayname(resourceName);
		resource.setTypeid(resourceType);
		resource.setRemark(remark);
		resource.setEnable(enable);
		resource.setAddtime(DateUtil.date());
		resource.setCreaterid(curUserId);
		resource.setViewname(viewName);
		return resourceDao.insert(resource);
	}
	
	/**
	 * 更新资源信息
	 * @param resource 被更新的资源信息
	 * @param resourceCode 新的资源编码
	 * @param resourceName 新的资源名称
	 * @param resourceType 新的资源类型
	 * @param remark 新的备注
	 * @param enable 新的可用状态
	 * @param viewName 新的视图名称
	 * @return
	 * @throws Exception
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	private Resource updateResource(Resource resource, String resourceCode, String resourceName, 
			String resourceType, String remark, Boolean enable, String viewName) throws Exception{
		List<Resource> resources = resourceDao.search(Cnd.where(Resource.FIELD_CODE, "=", resourceCode));
		if (resources.size() > 0) {
			throw new Exception("编码已存在");
		}
		resource.setCode(resourceCode);
		resource.setDisplayname(resourceName);
		resource.setTypeid(resourceType);
		resource.setRemark(remark);
		resource.setEnable(enable);
		resource.setViewname(viewName);
		resourceDao.update(resource);
		return resource;
	}
	
	/**
	 * 根据资源主键删除信息
	 * @param id 主键
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void delResource(String id){
		resourceDao.delete(id);
	}
	
	/**
	 * 根据以","隔开的资源主键字符串删除信息
	 * @param ids 以","隔开的主键字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void delResources(String ids){
		Criteria cri = Cnd.cri();
		cri.where().andIn(Resource.FIELD_ID, ids.split(","));
		resourceDao.clear(cri);
	}
	
	/**
	 * 获得所有的资源类型
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<ResourceType> getAllResourceTypes(){
		return resourceTypeDao.search();
	}
	
	/**
	 * 根据父级权限获得子级权限信息，并且标识出已与传入资源关联的权限
	 * @param parentId 父级权限ID
	 * @param resId 资源ID
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public List<TreeNode> getActionTreeNodes(String parentId, String resId){
		List<Action> actions = actionDao.search(Cnd.where(Action.FIELD_PARENTID, "=", parentId));
		List<Action> selActions = actionDao.getActionsForResource(resId, Cnd.where(Action.FIELD_PARENTID, "=", parentId));
		List<TreeNode> treeNodes = new ArrayList<TreeNode>();
		for (Action action : actions) {
			TreeNode treeNode = new TreeNode();
			treeNode.setId(action.getId());
			//如果节点包含子级，则标识此节点为父级并且不具有复选框
			if (null != action.getChildcount() && action.getChildcount() > 0) {
				treeNode.setIsParent(true);
				treeNode.setNocheck(true);
			}
			else {
				treeNode.setIsParent(false);
				treeNode.setNocheck(false);
			}
			treeNode.setName(action.getDisplayname());
			treeNode.setChecked(false);
			//如果节点与传入的资源已经关联，则默认为选中状态
			for (Action selAction : selActions) {
				if (selAction.getId().equals(action.getId())) {
					treeNode.setChecked(true);
					break;
				}
			}
			treeNodes.add(treeNode);
		}
		return treeNodes;
	}
	
	/**
	 * 关联资源和权限
	 * @param resId 资源ID
	 * @param actionIdsString 以","隔开的权限ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月4日
	 */
	public void saveSelActions(String resId, String actionIdsString){
		//先删除掉旧的关联信息，再保存新的信息
		actionResourceDao.clear(Cnd.where(ActionResource.FIELD_RESOURCEID, "=", resId));
		String[] actionIds = actionIdsString.split(",");
		for (String actionId : actionIds) {
			Action action = actionDao.get(actionId);
			if (null != action && action.getChildcount() == 0) {
				ActionResource actionResource = new ActionResource();
				actionResource.setActionid(actionId);
				actionResource.setResourceid(resId);
				actionResourceDao.insert(actionResource);
			}
		}
	}
}
